#include <iostream>
#include <memory>
using namespace std;
// class Fruite
// {
// public:
//     virtual void name() = 0;
// };
// class Apple : public Fruite
// {
// public:
//     void name() override
//     {
//         cout << "我是苹果" << endl;
//     }
// };
// class Banana : public Fruite
// {
// public:
//     void name() override
//     {
//         cout << "我是香蕉" << endl;
//     }
// };

// // 简单工厂的实现
// class FriuteFactory
// {
// public:
//     static shared_ptr<Fruite> create(const string &name)
//     {
//         if (name == "苹果")
//         {
//             return make_shared<Apple>();
//         }
//         else if (name == "Binary")
//         {
//             return make_shared<Binary>();
//         }
//         return shared_ptr<Fruite>();
//     }
// };

// 工厂方法的实现
// class FriuteFactory
// {
// public:
//     virtual shared_ptr<Fruite> create() = 0;
// };
// class AppleFactory : public FriuteFactory
// {
// public:
//     shared_ptr<Fruite> create()
//     {
//         return make_shared<Apple>();
//     }
// };
// class BananaFactory : public FriuteFactory
// {
// public:
//     shared_ptr<Fruite> create()
//     {
//         return make_shared<Banana>();
//     }
// };
class Fruite
{
public:
    virtual void name() = 0;
};
class Apple : public Fruite
{
public:
    void name() override
    {
        cout << "我是苹果" << endl;
    }
};
class Banana : public Fruite
{
public:
    void name() override
    {
        cout << "我是香蕉" << endl;
    }
};
class Animal
{
public:
    virtual void name() = 0;
};
class Lamp : public Animal
{
public:
    void name()
    {
        cout << "我是一只山羊" << endl;
    }
};
class Dog : public Animal
{
public:
    void name()
    {
        cout << "我是一只土狗" << endl;
    }
};

// 抽象工厂
class Factory
{
public:
    virtual shared_ptr<Fruite> GetFruit(const string &name) = 0;
    virtual shared_ptr<Animal> GetAnimal(const string &name) = 0;
};
class FruiteFactory : public Factory
{
public:
    shared_ptr<Animal> GetAnimal(const string &name)
    {
        return shared_ptr<Animal>();
    }
    shared_ptr<Fruite> GetFruit(const string &name)
    {
        if (name == "苹果")
        {
            return make_shared<Apple>();
        }
        else
        {
            return make_shared<Banana>();
        }
        return shared_ptr<Fruite>();
    }
};
class AnimalFactory : public Factory
{
public:
    shared_ptr<Animal> GetAnimal(const string &name)
    {
        if (name == "山羊")
        {
            return make_shared<Lamp>();
        }
        else
        {
            return make_shared<Dog>();
        }
        return shared_ptr<Animal>();
    }
    shared_ptr<Fruite> GetFruit(const string &name)
    {
        return shared_ptr<Fruite>();
    }
};

class FactoryProduct
{
public:
    static shared_ptr<Factory> create(const string &name)
    {
        if (name == "水果")
        {
            return make_shared<FruiteFactory>();
        }
        else
        {
            return make_shared<AnimalFactory>();
        }
        return shared_ptr<Factory>();
    }
};

int main()
{
    shared_ptr<Factory> ff = FactoryProduct::create("水果");
    shared_ptr<Fruite> fruite = ff->GetFruit("苹果");
    if (fruite.get() == nullptr)
    {
        return -1;
    }
    fruite->name();
    fruite = ff->GetFruit("香蕉");
    if (fruite.get() == nullptr)
    {
        return -1;
    }
    fruite->name();

    shared_ptr<Factory> factory = FactoryProduct::create("动物");
    shared_ptr<Animal> animal = factory->GetAnimal("山羊");
    if (animal.get() == nullptr)
    {
        return -1;
    }
    animal->name();
    animal = factory->GetAnimal("土狗");
    if (animal.get() == nullptr)
    {
        return -1;
    }
    animal->name();

    // shared_ptr<FriuteFactory> ff = make_shared<AppleFactory>();
    // shared_ptr<Fruite> fruite = ff->create();
    // fruite->name();
    // ff.reset(new BananaFactory());
    // fruite = ff->create();
    // fruite->name();

    return 0;
}